#!/usr/bin/env python
# -*- coding: utf-8 -*-

import base64
import hashlib
import tkinter as tk
from tkinter import ttk, messagebox
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

class TextCryptoApp:
    def __init__(self, root):
        self.root = root
        self.root.title("文本加密解密工具")
        self.root.geometry("600x450")
        self.root.resizable(True, True)
        
        # 设置样式
        self.style = ttk.Style()
        self.style.configure('TButton', font=('微软雅黑', 10))
        self.style.configure('TLabel', font=('微软雅黑', 10))
        
        # 创建主框架
        main_frame = ttk.Frame(root, padding="10")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 密码输入区域
        password_frame = ttk.Frame(main_frame)
        password_frame.pack(fill=tk.X, pady=5)
        
        ttk.Label(password_frame, text="密码: ").pack(side=tk.LEFT)
        self.password_var = tk.StringVar()
        self.password_entry = ttk.Entry(password_frame, textvariable=self.password_var, show="*")
        self.password_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)
        
        # 加解密算法选择
        algo_frame = ttk.Frame(main_frame)
        algo_frame.pack(fill=tk.X, pady=5)
        
        ttk.Label(algo_frame, text="算法: ").pack(side=tk.LEFT)
        self.algorithm = tk.StringVar(value="AES")
        algorithms = ["AES", "Base64", "自定义异或"]
        algo_combo = ttk.Combobox(algo_frame, textvariable=self.algorithm, values=algorithms, state="readonly")
        algo_combo.pack(side=tk.LEFT, fill=tk.X, expand=True)
        
        # 输入文本区域
        input_frame = ttk.LabelFrame(main_frame, text="输入文本")
        input_frame.pack(fill=tk.BOTH, expand=True, pady=5)
        
        self.input_text = tk.Text(input_frame, wrap=tk.WORD)
        self.input_text.pack(fill=tk.BOTH, expand=True)
        
        # 按钮区域
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill=tk.X, pady=5)
        
        self.encrypt_btn = ttk.Button(button_frame, text="加密", command=self.encrypt_text)
        self.encrypt_btn.pack(side=tk.LEFT, padx=5)
        
        self.decrypt_btn = ttk.Button(button_frame, text="解密", command=self.decrypt_text)
        self.decrypt_btn.pack(side=tk.LEFT, padx=5)
        
        self.clear_btn = ttk.Button(button_frame, text="清空", command=self.clear_text)
        self.clear_btn.pack(side=tk.LEFT, padx=5)
        
        # 输出文本区域
        output_frame = ttk.LabelFrame(main_frame, text="输出文本")
        output_frame.pack(fill=tk.BOTH, expand=True, pady=5)
        
        self.output_text = tk.Text(output_frame, wrap=tk.WORD)
        self.output_text.pack(fill=tk.BOTH, expand=True)
        
        # 底部状态栏
        self.status_var = tk.StringVar()
        self.status_var.set("就绪")
        status_bar = ttk.Label(root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)
    
    def derive_key(self, password):
        """从密码生成密钥"""
        if self.algorithm.get() == "AES":
            # 生成16字节(128位)密钥
            return hashlib.sha256(password.encode()).digest()[:16]
        else:
            # 对于其他算法，返回原始密码
            return password.encode()
    
    def encrypt_text(self):
        """加密文本"""
        try:
            text = self.input_text.get(1.0, tk.END).strip()
            if not text:
                messagebox.showwarning("警告", "请输入要加密的文本")
                return
            
            password = self.password_var.get()
            if not password and self.algorithm.get() != "Base64":
                messagebox.showwarning("警告", "请输入密码")
                return
            
            if self.algorithm.get() == "AES":
                key = self.derive_key(password)
                cipher = AES.new(key, AES.MODE_CBC)
                ct_bytes = cipher.encrypt(pad(text.encode('utf-8'), AES.block_size))
                iv = base64.b64encode(cipher.iv).decode('utf-8')
                ct = base64.b64encode(ct_bytes).decode('utf-8')
                result = f"{iv}:{ct}"
            
            elif self.algorithm.get() == "Base64":
                result = base64.b64encode(text.encode('utf-8')).decode('utf-8')
            
            elif self.algorithm.get() == "自定义异或":
                key = self.derive_key(password)
                key_bytes = key
                text_bytes = text.encode('utf-8')
                result_bytes = bytearray()
                
                for i, byte in enumerate(text_bytes):
                    key_byte = key_bytes[i % len(key_bytes)]
                    result_bytes.append(byte ^ key_byte)
                
                result = base64.b64encode(result_bytes).decode('utf-8')
            
            self.output_text.delete(1.0, tk.END)
            self.output_text.insert(1.0, result)
            self.status_var.set("加密完成")
        
        except Exception as e:
            messagebox.showerror("错误", f"加密过程中出错: {str(e)}")
            self.status_var.set(f"错误: {str(e)}")
    
    def decrypt_text(self):
        """解密文本"""
        try:
            text = self.input_text.get(1.0, tk.END).strip()
            if not text:
                messagebox.showwarning("警告", "请输入要解密的文本")
                return
            
            password = self.password_var.get()
            if not password and self.algorithm.get() != "Base64":
                messagebox.showwarning("警告", "请输入密码")
                return
            
            if self.algorithm.get() == "AES":
                try:
                    iv, ct = text.split(':', 1)
                    iv = base64.b64decode(iv)
                    ct = base64.b64decode(ct)
                    key = self.derive_key(password)
                    cipher = AES.new(key, AES.MODE_CBC, iv)
                    pt = unpad(cipher.decrypt(ct), AES.block_size)
                    result = pt.decode('utf-8')
                except ValueError:
                    messagebox.showerror("错误", "无效的加密文本格式或密码错误")
                    return
            
            elif self.algorithm.get() == "Base64":
                try:
                    result = base64.b64decode(text).decode('utf-8')
                except:
                    messagebox.showerror("错误", "无效的Base64编码")
                    return
            
            elif self.algorithm.get() == "自定义异或":
                try:
                    key = self.derive_key(password)
                    key_bytes = key
                    text_bytes = base64.b64decode(text)
                    result_bytes = bytearray()
                    
                    for i, byte in enumerate(text_bytes):
                        key_byte = key_bytes[i % len(key_bytes)]
                        result_bytes.append(byte ^ key_byte)
                    
                    result = result_bytes.decode('utf-8')
                except:
                    messagebox.showerror("错误", "解密失败，可能是密码错误")
                    return
            
            self.output_text.delete(1.0, tk.END)
            self.output_text.insert(1.0, result)
            self.status_var.set("解密完成")
        
        except Exception as e:
            messagebox.showerror("错误", f"解密过程中出错: {str(e)}")
            self.status_var.set(f"错误: {str(e)}")
    
    def clear_text(self):
        """清空输入和输出文本框"""
        self.input_text.delete(1.0, tk.END)
        self.output_text.delete(1.0, tk.END)
        self.status_var.set("已清空")

def main():
    root = tk.Tk()
    app = TextCryptoApp(root)
    root.mainloop()

if __name__ == "__main__":
    main() 